package com.cjh.mybatis06.executor.resultset;

import com.cjh.mybatis06.executor.Executor;
import com.cjh.mybatis06.mapping.BoundSql;
import com.cjh.mybatis06.mapping.MappedStatement;

import java.lang.reflect.Method;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;

/**
 * @Descripton 默认map结果处理器
 * @Author cjh
 * @Date 2023/6/1 10:28
 */
public class DefaultResultSetHandler implements ResultSetHandler{

    private final BoundSql boundSql;

    public DefaultResultSetHandler(Executor executor, MappedStatement mappedStatement,BoundSql boundSql) {
        this.boundSql = boundSql;
    }

    @Override
    public <E> List<E> handleResultSets(Statement statement) throws SQLException {
        ResultSet resultSet = statement.getResultSet();
        try {
            return resultSet2Obj(resultSet, Class.forName(boundSql.getResultType()));
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
            return null;
        }

    }



    private <T> List<T> resultSet2Obj(ResultSet resultSet, Class<?> clazz) {
        ArrayList<T> list = new ArrayList<>();
        try {
            ResultSetMetaData metaData = resultSet.getMetaData();
            int columnCount = metaData.getColumnCount();
//            每次遍历行值
            while (resultSet.next()) {
//                创建一个 返回的对象 resultType类型
                T obj = (T) clazz.newInstance();
                for (int i = 1; i <= columnCount; i++) {
//                    todo  没太看懂
//                    第一列。。。 id
                    Object value = resultSet.getObject(i);
                    String columnName = metaData.getColumnName(i);
//                    方法名称---setId
                    String setMethod = "set" + columnName.substring(0, 1).toUpperCase()
                            + columnName.substring(1);
                    Method method;
                    if (value instanceof Timestamp) {
                        method = clazz.getMethod(setMethod, Date.class);
                    } else {
                        method = clazz.getMethod(setMethod, value.getClass());
                    }
//                    反射调用
                    method.invoke(obj, value);
                }
                list.add(obj);
            }

        } catch (Exception e) {
            e.printStackTrace();

        }
        return list;
    }
}
